#include "dashboard1.h"
#include <QPainter>
#include <QDebug>
#include <QtMath>

Dashboard::Dashboard(QWidget *parent) : QWidget(parent)
{
    if(this->animation == true)
    {
        QTimer::singleShot(50, this, SLOT(updateValue()));
    }
}
Dashboard::~Dashboard()
{

}
void Dashboard::paintEvent(QPaintEvent *)
{
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);

    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);/*使用反锯齿(如果可用) */
    painter.translate(width / 2, height / 2); /* 坐标变换为窗体中心 */
    painter.scale(side / 200.0, side / 200.0); /* 比例缩放 */

    drawRing(&painter);
    drawScale(&painter);
    drawScaleNum(&painter);
    drawPointer(&painter);
    drawValue(&painter);
}

void Dashboard::drawRing(QPainter *painter)
{
    int radius = 100;
    painter->save();

    QPen pen;
    pen.setCapStyle(Qt::FlatCap);
    pen.setWidthF(ringWidth);

    radius = radius - ringWidth;
    QRectF rect = QRectF(-radius, -radius, radius * 2, radius * 2);

    //计算总范围角度,根据占比例自动计算三色圆环范围角度
    double angleAll = 360.0 - startAngle - endAngle;
    double angleStart = angleAll * (double)ringStartPercent / 100;
    double angleMidLeft = angleAll * (double)ringMidLeftPercent / 100;
    double angleMid = angleAll * (double)ringMidPercent / 100;
    double angleMidRight = angleAll * (double)ringMidRightPercent / 100;
    double angleEnd = angleAll * (double)ringEndPercent / 100;

    //绘制第一圆环
    pen.setColor(ringColorStart);
    painter->setPen(pen);
    painter->drawArc(rect, (270 - startAngle - angleStart) * 16, angleStart * 16);

    pen.setColor(ringColorMidLeft);
    painter->setPen(pen);
    painter->drawArc(rect, (270 - startAngle - angleStart - angleMidLeft) * 16, angleMidLeft * 16);

    //绘制第二圆环
    pen.setColor(ringColorMid);
    painter->setPen(pen);
    painter->drawArc(rect, (270 - startAngle - angleStart - angleMidLeft- angleMid) * 16, angleMid * 16);

    pen.setColor(ringColorMidRight);
    painter->setPen(pen);
    painter->drawArc(rect, (270 - startAngle - angleStart - angleMidLeft- angleMid - angleMidRight) * 16, angleMidRight * 16);

    //绘制第三圆环
    pen.setColor(ringColorEnd);
    painter->setPen(pen);
    painter->drawArc(rect, (270 - startAngle - angleStart - angleMidLeft - angleMid -angleMidRight - angleEnd) * 16, angleEnd * 16);

    painter->restore();
}

void Dashboard::drawScale(QPainter *painter)
{
    int radius = 94;
    painter->save();

    QPen pen;
    pen.setColor(textColor);
    pen.setCapStyle(Qt::RoundCap);

    painter->rotate(startAngle);
    int steps = (scaleMajor * scaleMinor);
    double angleStep = (360.0 - startAngle - endAngle) / steps;

    //计算圆环对应大刻度范围索引
    int indexStart = steps * (double)ringStartPercent / 100 + 1;
    int indexMidLeft = steps * (double)ringMidLeftPercent / 100 - 1;
    int indexMid = steps * (double)ringMidPercent / 100 - 1;
    int indexMidRight = steps * (double)ringMidRightPercent / 100 - 1;
    int indexEnd = steps * (double)ringEndPercent / 100 + 1;
    int index = 0;
    //qDebug("drawScale index=%d indexStart=%d", index, indexStart);
    for (int i = 0; i <= steps; i++) {
        //if (i % scaleMinor == 0) {
            //根据所在圆环范围切换颜色
            if (index < indexStart) {
                pen.setColor(ringColorStart);
            } else if (index < (indexStart + indexMidLeft+1)) {
               pen.setColor(ringColorMidLeft);
            }
            else if (index < (indexStart + indexMid + indexMidLeft+1)) {
                pen.setColor(ringColorMid);
            }
            else if (index <= (indexStart + indexMid + indexMidLeft + indexMidRight + 1)) {
                pen.setColor(ringColorMidRight);
            }
            else if (index < (indexStart + indexMid + indexMidLeft + indexMidRight + indexEnd)) {
                pen.setColor(ringColorEnd);
            }

            index++;
       if (i % scaleMinor == 0){
            pen.setWidthF(0.5); //1.5
            painter->setPen(pen);
            painter->drawLine(0, radius - 5 - ringWidth, 0, radius - ringWidth+1);
        } else {
            pen.setWidthF(0.5);
            painter->setPen(pen);
            painter->drawLine(0, radius - 3 - ringWidth, 0, radius - ringWidth+1);
        }

        painter->rotate(angleStep);
    }

    painter->restore();
}

void Dashboard::drawScaleNum(QPainter *painter)
{
    int radius = 70;
    painter->save();
    painter->setPen(textColor);

    double startRad = (360 - startAngle - 90) * (M_PI / 180);
    double deltaRad = (360 - startAngle - endAngle) * (M_PI / 180) / scaleMajor;

    for (int i = 0; i <= scaleMajor; i++) {
        double sina = qSin(startRad - i * deltaRad);
        double cosa = qCos(startRad - i * deltaRad);
        double value = 1.0 * i * ((maxValue - minValue) / scaleMajor) + minValue;
        if(value >= -3.00 && value <= 3.00)
            painter->setPen(ringColorMid);
        else {
            painter->setPen(textColor);
        }
        QString strValue = QString("%1").arg((double)value, 0, 'f', 0);
        double textWidth = fontMetrics().width(strValue);
        double textHeight = fontMetrics().height();
        int x = radius * cosa - textWidth / 2;
        int y = -radius * sina + textHeight / 4;
        painter->drawText(x, y, strValue);
    }

    painter->restore();
}

void Dashboard::settextvalue(QString text)
{
    textValue = text;
}

void Dashboard::setcurrentvalue(double value)
{
    currentValue = value;
}
void Dashboard::drawPointer(QPainter *painter)
{
    int radius = 62;
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(pointerColor);

    QPolygon pts;
    pts.setPoints(4, -5, 0, 0, -8, 5, 0, 0, radius);

    painter->rotate(startAngle);
    if(maxValue < currentValue)
        currentValue = maxValue;
    else  if(minValue > currentValue)
        currentValue = minValue;

    double degRotate = (360.0 - startAngle - endAngle) / (maxValue - minValue) * (currentValue - minValue);
    painter->rotate(degRotate);
    painter->drawConvexPolygon(pts);

    painter->restore();
}

void Dashboard::drawValue(QPainter *painter)
{
    int radius = 100;
    painter->save();
    painter->setPen(textColor);
    //painter->setBrush(QColor(255,0,0,255));
    QFont font;
    font.setPixelSize(12);
    font.setFamily("微软雅黑");
    painter->setFont(font);

    // QRectF textRect(-radius, radius / 2, radius * 2, radius / 3);
    QRectF textRect(-radius/4, radius / 4, radius/4*2, radius / 4);
    painter->drawRect(textRect); //增加一个矩形框
    painter->setPen(Qt::black);
    QString strValue = QString("%1").arg((double)currentValue, 0, 'f', precision);
    painter->drawText(textRect, Qt::AlignCenter, strValue);

    painter->setPen(textColor);
    QRectF text(-radius/2, -radius / 2, radius, radius / 4);
    //painter->drawRect(text); //增加一个矩形框
    textValue="温度";
    painter->drawText(text, Qt::AlignCenter, textValue);

    painter->restore();
}
double Dashboard::getMinValue()const
{
    return this->minValue;
}
double Dashboard::getMaxValue()const
{
    return this->maxValue;
}
double Dashboard::getValue()const
{
    return this->currentValue;
}
int Dashboard::getPrecision()const
{
    return this->precision;
}
int Dashboard::getScaleMajor()const
{
    return this->scaleMajor;
}
int Dashboard::getScaleMinor()const
{
    return this->scaleMinor;
}
int Dashboard::getStartAngle()const
{
    return this->startAngle;
}
int Dashboard::getEndAngle()const
{
    return this->endAngle;
}
bool Dashboard::getAnimation()const
{
    return this->animation;
}
double Dashboard::getAnimationStep()const
{
    return this->animationStep;
}
int Dashboard::getRingWidth()const
{
    return  this->ringWidth;
}
int Dashboard::getRingStartPercent()const
{
    return this->ringStartPercent;
}
int Dashboard::getRingMidPercent()const
{
    return this->ringMidPercent;
}
int Dashboard::getRingEndPercent()const
{
    return  this->ringEndPercent;
}
QColor Dashboard::getRingColorStart()      const
{
    return this->ringColorStart;
}
QColor Dashboard::getRingColorMid()        const
{
    return this->ringColorMid;
}
QColor Dashboard::getRingColorEnd()        const
{
    return this->ringColorEnd;
}
QColor Dashboard::getPointerColor()        const
{
    return this->pointerColor;
}
QColor Dashboard::getTextColor()           const
{
    return this->textColor;
}

QSize Dashboard::sizeHint()const
{
    int width = this->width();
    int height = this->height();

    return QSize(qMin(width, height), qMin(width, height));
}
QSize Dashboard::minimumSizeHint()const
{
    int width = this->width();
    int height = this->height();

    return QSize(qMin(width, height), qMin(width, height));
}

void Dashboard::setRange(double minValue, double maxValue)
{
    this->minValue = minValue;
    this->maxValue = maxValue;
}
void Dashboard::setRange(int minValue, int maxValue)
{
    this->minValue = minValue;
    this->maxValue = maxValue;
}
//设置最大最小值
void Dashboard::setMinValue(double minValue)
{
    this->minValue = minValue;
}
void Dashboard::setMaxValue(double maxValue)
{
    this->maxValue = maxValue;
}

//设置目标值
void Dashboard::setValue(double value)
{
    this->value = value;
    if(this->animation == true)
    {
        QTimer::singleShot(5, this, SLOT(updateValue()));
    }
    else {
        this->currentValue = this->value;
    }
    update();
}
void Dashboard::setValue(int value)
{
    this->value =value;
    if(this->animation == true)
    {
        QTimer::singleShot(5, this, SLOT(updateValue()));
    }
    else {
        this->currentValue = this->value;
    }
    update();
}
void Dashboard::setValue(const QString &value)
{
    this->value = value.toDouble();
    if(this->animation == true)
    {
        QTimer::singleShot(5, this, SLOT(updateValue()));
    }
    else {
        this->currentValue = this->value;
    }
    update();
}

//设置精确度
void Dashboard::setPrecision(int precision)
{
    this->precision = precision;
}
//设置主刻度数量
void Dashboard::setScaleMajor(int scaleMajor)
{
    this->scaleMajor = scaleMajor;
}
//设置小刻度数量
void Dashboard::setScaleMinor(int scaleMinor)
{
    this->scaleMinor = scaleMinor;
}
//设置开始旋转角度
void Dashboard::setStartAngle(int startAngle)
{
    this->startAngle = startAngle;
}
//设置结束旋转角度
void Dashboard::setEndAngle(int endAngle)
{
    this->endAngle = endAngle;
}

//设置是否启用动画显示
void Dashboard::setAnimation(bool animation)
{
    this->animation = animation;
    if(this->animation == true)
    {
        QTimer::singleShot(5, this, SLOT(updateValue()));
    }
}
//设置动画显示的步长
void Dashboard::setAnimationStep(double animationStep)
{
    this->animationStep = animationStep;
}
void Dashboard::setRingWidth(int ringWidth)
{
    this->ringWidth = ringWidth;
}

//设置三个圆环所占比例
void Dashboard::setRingStartPercent(int ringStartPercent)
{
    this->ringStartPercent = ringStartPercent;
}
void Dashboard::setRingMidPercent(int ringMidPercent)
{
    this->ringMidPercent = ringMidPercent;
}
void Dashboard::setRingEndPercent(int ringEndPercent)
{
    this->ringEndPercent = ringEndPercent;
}

//设置三个圆环颜色
void Dashboard::setRingColorStart(const QColor &ringColorStart)
{
    this->ringColorStart = ringColorStart;
}
void Dashboard::setRingColorMid(const QColor &ringColorMid)
{
    this->ringColorMid = ringColorMid;
}
void Dashboard::setRingColorEnd(const QColor &ringColorEnd)
{
    this->ringColorEnd = ringColorEnd;
}

//设置指针颜色
void Dashboard::setPointerColor(const QColor &pointerColor)
{
    this->pointerColor = pointerColor;
}
//设置文本颜色
void Dashboard::setTextColor(const QColor &textColor)
{
    this->textColor = textColor;
}
void Dashboard::updateValue()
{
    if(this->animation == true)
    {
        if(fabs(currentValue - value) > 0.001)
        {
            if(currentValue - value > 0.001)
                currentValue = currentValue - animationStep;
            else {
                currentValue = currentValue + animationStep;
            }
            QTimer::singleShot(5, this, SLOT(updateValue()));
            update();
        }
    }
}
